package Mongo

import (
	"context"
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Args"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.mongodb.org/mongo-driver/mongo/readpref"
	"strings"
	"time"
	//	_ "github.com/mattn/go-sqlite3" //具体使用的时候，请在服务中，某个go文件中import这一句话
	//	_ "github.com/go-sql-driver/mysql" //具体使用的时候，请在服务中，某个go文件中import这一句话
)

type db struct {
	db *mongo.Database
}

func (e *db) disconnect() {
	if e.db != nil {
		if e.db.Client() != nil {
			e.db.Client().Disconnect(context.TODO())
		}
		e.db = nil
	}
}

func (e *db) connect() error {
	e.disconnect()

	// 从命令行取出连接参数
	option, err := e.buildOptions()
	if err != nil {
		return err
	}

	// 连接到MongoDB
	client, err := mongo.Connect(context.TODO(), option)
	if err != nil {
		return err
	}

	// 检查连接
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel()
	err = client.Ping(ctx, readpref.Primary())
	if err != nil {
		return err
	}

	// 打开默认的数据库
	db := Args.GetArgs("mongo.database=", "")
	database := client.Database(db)
	if database == nil {
		client.Disconnect(context.TODO())
		return errors.New("连接数据库失败：" + db)
	}

	e.db = database
	return nil
}

func (e *db) buildOptions() (*options.ClientOptions, error) {
	host := Args.GetArgs("mongo.host=", "localhost")
	if host == "" {
		return nil, errors.New("缺失参数：mongo.host")
	}

	port := Args.GetArgs("mongo.port=", "27017")
	if port == "" {
		return nil, errors.New("缺失参数：mongo.port")
	}

	username := Args.GetArgs("mongo.username=", "")
	if username == "" {
		return nil, errors.New("缺失参数：mongo.username")
	}

	password := Args.GetArgs("mongo.password=", "")
	if password == "" {
		return nil, errors.New("缺失参数：mongo.password")
	}

	database := Args.GetArgs("mongo.database=", "")
	if database == "" {
		return nil, errors.New("缺失参数：mongo.database")
	}

	replSetName := Args.GetArgs("mongo.replSetName=", "configsvr")
	if replSetName == "" {
		return nil, errors.New("缺失参数：mongo.replSetName")
	}

	safe := Args.GetArgs("mongo.safe=", "true")
	if safe == "" {
		return nil, errors.New("缺失参数：mongo.safe")
	}

	slaveOk := Args.GetArgs("mongo.slaveOk=", "true")
	if slaveOk == "" {
		return nil, errors.New("缺失参数：mongo.slaveOk")
	}

	// 定义数据库连接信息
	sb := strings.Builder{}
	sb.WriteString("mongodb://")
	sb.WriteString(username)
	sb.WriteString(":")
	sb.WriteString(password)
	sb.WriteString("@")
	sb.WriteString(host)
	sb.WriteString(":")
	sb.WriteString(port)
	sb.WriteString("/")
	sb.WriteString(database)
	sb.WriteString("?authSource=")
	sb.WriteString(database)
	sb.WriteString("&replSetName=")
	sb.WriteString(replSetName)
	sb.WriteString("&safe=")
	sb.WriteString(safe)
	sb.WriteString("&slaveOk=")
	sb.WriteString(slaveOk)

	uri := sb.String()
	return options.Client().ApplyURI(uri), nil
}

func (e *db) Collection(name string) *mongo.Collection {
	return DB.db.Collection(name)
}
